
#include "stdafx.h"
#include "ConstDef.h"
#include "ReloadCode.h"
#include "ReloadPacket.h"
#include "ReloadConfigure.h"
#include "ReloadApp.h"
#include "ReloadPacket.h"
#include "ReloadOverlay.h"
#include "ReloadNetworkDataHandler.h"
#include "ReloadConnectionActor.h"
#include "ReloadAcceptActor.h"

namespace reload
{
	ReloadAcceptActorMgr::ReloadAcceptActorMgr( boost::weak_ptr<ReloadOverlay> _pReloadOverlay ,boost::shared_ptr<asyframe::WorkerBase> _pWorker, boost::shared_ptr<ReloadConnectionActorMgr> _pReloadConnectionActorMgr )
	:asyframe::AssignedSingleWorkerActorMgr(_pWorker),pReloadConnectionActorMgr_(_pReloadConnectionActorMgr),pReloadOverlay_(_pReloadOverlay)
	{

	}

	ReloadAcceptActorMgr::~ReloadAcceptActorMgr()
	{
		pReloadConnectionActorMgr_.reset();
		pReloadOverlay_.reset();
	}

	retT ReloadAcceptActorMgr::makeActor( boost::shared_ptr<asyframe::ActorBase>& _pActor )
	{
		_pActor.reset(new ReloadAcceptActor(pReloadOverlay_));
		R(asyframe::ActorMgrBase::makeActor(_pActor));
		RETSUCCESS;
	}

	retT ReloadAcceptActorMgr::start()
	{
		R(justMakeActor());
		R(asyframe::ActorMgrBase::start());
		RETSUCCESS;
	}

	boost::shared_ptr<ReloadConnectionActorMgr> ReloadAcceptActorMgr::getReloadConnectionActorMgr()
	{
		return pReloadConnectionActorMgr_.lock();
	}

	ReloadAcceptActor::ReloadAcceptActor(boost::weak_ptr<ReloadOverlay> _pReloadOverlay)
	:pAcceptHandler_(),pReloadOverlay_(_pReloadOverlay)
	{

	}

	ReloadAcceptActor::~ReloadAcceptActor()
	{
		pAcceptHandler_.reset();
		pReloadOverlay_.reset();
	}

	retT ReloadAcceptActor::init()
	{
		R(asyframe::ActorBase::init());
		boost::shared_ptr<ReloadOverlay> pReloadOverlay = pReloadOverlay_.lock();
		if(!pReloadOverlay)
			RET(ERROR_COMMON_SHARED_PTR_NULL);
		boost::unordered_map<asyframe::uint32, ReloadAppOverlayConfigure>::iterator it = ((ReloadAppConfigure*)asyframe::getApp()->getConfigure())->overlay_.find(pReloadOverlay->overlayNameHash_);
		if(it == ((ReloadAppConfigure*)asyframe::getApp()->getConfigure())->overlay_.end())
			RET(ERROR_COMMON_CONTAINER_ELEMENT_NOT_EXIST);
		pAcceptHandler_.reset(new asyframe::AcceptHandler());
		boost::shared_ptr<boost::asio::ip::tcp::endpoint> pLocalEndpoint(new boost::asio::ip::tcp::endpoint(
			boost::asio::ip::address::from_string(it->second.listenIP_), it->second.listenPort_));
		pAcceptHandler_->setLocalEndpoint(pLocalEndpoint);
		pAcceptHandler_->attachHandlerOwner(shared_from_this());
		RETSUCCESS;
	}

	retT ReloadAcceptActor::onError( retT errorNo )
	{
		errorNo = asyframe::ActorBase::onError(errorNo);
		if(boost::shared_ptr<asyframe::ActorMgrBase> pActorMgr = pActorMgr_.lock())
		{
			pActorMgr->post(boost::bind(&asyframe::ActorMgrBase::checkToStopApp, pActorMgr));
		}
		return errorNo;
	}

	retT ReloadAcceptActor::start()
	{
		R(asyframe::ActorBase::start());
		R(acceptOne());
		RETSUCCESS;
	}

	retT ReloadAcceptActor::onAccept( boost::shared_ptr<asyframe::AcceptHandlerContext> _pAcceptHandlerContext, const boost::system::error_code& e, std::size_t _timeoutCount )
	{
		_R(asyframe::IAcceptAction::onAccept(_pAcceptHandlerContext, e, _timeoutCount))
		{
			if(ret.status_ && (ret.status_&NOLOGMSK) != INFO_IACTIONBASE_TIMER_OPERATION_ABORT && _pAcceptHandlerContext && _pAcceptHandlerContext->pAcceptedActor_)
				R(_pAcceptHandlerContext->pAcceptedActor_->post(boost::bind(&asyframe::ActorBase::close, _pAcceptHandlerContext->pAcceptedActor_)));
		}R_
		if(_pAcceptHandlerContext && _pAcceptHandlerContext->pAcceptedActor_)
		{
			if(!e)
			{
				boost::shared_ptr<ReloadConnectionActor> pReloadConnectionActor = boost::dynamic_pointer_cast<ReloadConnectionActor>(_pAcceptHandlerContext->pAcceptedActor_);
				if(!pReloadConnectionActor)
					RET(ERROR_COMMON_SHARED_PTR_NULL);
				R(_pAcceptHandlerContext->pAcceptedActor_->post(boost::bind(&asyframe::ActorBase::start, _pAcceptHandlerContext->pAcceptedActor_)));
				R(_pAcceptHandlerContext->pAcceptedActor_->post(boost::bind(&ReloadConnectionActor::startAfterAccepted, pReloadConnectionActor)));
			}
			else
			{
				R(_pAcceptHandlerContext->pAcceptedActor_->post(boost::bind(&asyframe::ActorBase::close, _pAcceptHandlerContext->pAcceptedActor_)));
			}
		}
		if(_pAcceptHandlerContext)
			_pAcceptHandlerContext->pTcpSocket_.reset();
		if(e == boost::asio::error::operation_aborted)
			RETSUCCESS;
		if(e)
		{
			LOG_INFO(boost::format( "errorNo %1% : %2% in %3% %4% %5%" ) % e.value() % e.message() % __FUNCTION__ % __FILE__ % __LINE__);
		}
		R(acceptOne());
		RETSUCCESS;
	}

	retT ReloadAcceptActor::acceptOne()
	{
		boost::shared_ptr<asyframe::AcceptHandlerContext> pAcceptHandlerContext(new asyframe::AcceptHandlerContext());
		boost::shared_ptr<asyframe::ActorBase> pAcceptedActor;
		boost::shared_ptr<ReloadAcceptActorMgr> pReloadAcceptActorMgr = boost::dynamic_pointer_cast<ReloadAcceptActorMgr>(pActorMgr_.lock());
		if(!pReloadAcceptActorMgr)
			RET(ERROR_COMMON_SHARED_PTR_NULL);
		if(boost::shared_ptr<asyframe::ActorMgrBase> pTcpConnectionActorMgr = pReloadAcceptActorMgr->getReloadConnectionActorMgr())
		{
			R(pTcpConnectionActorMgr->makeActor(pAcceptedActor));
		}
		else
		{
			RET(ERROR_COMMON_SHARED_PTR_NULL);
		}
		pAcceptHandlerContext->pAcceptedActor_ = pAcceptedActor;
		R(pAcceptHandler_->asyncAccept(boost::dynamic_pointer_cast<asyframe::IAcceptableActor>(pAcceptedActor)->getTcpSocket(),
			pAcceptHandlerContext,
			boost::bind(&ReloadAcceptActor::onAccept,
			boost::dynamic_pointer_cast<ReloadAcceptActor>(shared_from_this()),
			pAcceptHandlerContext, _1, _2)));
		RETSUCCESS;
	}
} /*namespace reload*/
